package org.ghost.springboot2.demo.config;

import com.zaxxer.hikari.HikariDataSource;
import org.ghost.springboot2.demo.component.datasource.GhostRoutingDataSource;
import org.ghost.springboot2.demo.component.datasource.constant.DbContextEnum;
import org.ghost.springboot2.demo.component.datasource.properties.DataSourceConfigEntity;
import org.ghost.springboot2.demo.component.datasource.properties.GhostDataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DataSourceConfig {
    @Bean
    public DataSource ghostRoutingDataSource(GhostDataSourceProperties ghostDataSourceProperties) {
        Assert.notNull(ghostDataSourceProperties, "GhostDataSourceProperties is not null");
        Assert.notNull(ghostDataSourceProperties.getMaster(), "GhostDataSourceProperties.getMaster() is not null");
        Assert.notNull(ghostDataSourceProperties.getSlave(), "GhostDataSourceProperties.getSlave() is not null");

        Map<Object, Object> dataSourceMap = new HashMap<Object, Object>();
        //master
        HikariDataSource master = getDataSource(ghostDataSourceProperties.getMaster(), ghostDataSourceProperties);
        dataSourceMap.put(DbContextEnum.MASTER, master);

        //slave
        HikariDataSource slave = getDataSource(ghostDataSourceProperties.getSlave(), ghostDataSourceProperties);
        dataSourceMap.put(DbContextEnum.SLAVE, slave);

        GhostRoutingDataSource ghostRoutingDataSource = new GhostRoutingDataSource();
        ghostRoutingDataSource.setDefaultTargetDataSource(master);
        ghostRoutingDataSource.setTargetDataSources(dataSourceMap);
        return ghostRoutingDataSource;
    }

    private HikariDataSource getDataSource(DataSourceConfigEntity config, GhostDataSourceProperties ghostDataSourceProperties) {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setConnectionTestQuery(ghostDataSourceProperties.getValidationQuery());
        dataSource.setMaxLifetime((long) ghostDataSourceProperties.getMaxLifeTime());
        dataSource.setIdleTimeout((long) ghostDataSourceProperties.getIdleTimeout());
        dataSource.setMaximumPoolSize(config.getMaxPoolSize());
        dataSource.setMinimumIdle(config.getMinIdle());
        dataSource.setDriverClassName(config.getDriverClassName());
        dataSource.setJdbcUrl(config.getUrl());
        dataSource.setUsername(config.getUsername());
        dataSource.setPassword(config.getPassword());

        return dataSource;
    }
}
